#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/poll.h>
#include <sys/epoll.h>

#define DEVICE_FILE "/dev/chardev"

// 使用epoll测试
void test_epoll(int dev_fd)
{
    // 创建epoll实例
    int epoll_fd = epoll_create(16);
    struct epoll_event ev, events[8];
    ev.data.fd = STDIN_FILENO;
    ev.events = EPOLLIN;
    // 将文件描述符添加到epoll实例中
    epoll_ctl(epoll_fd, EPOLL_CTL_ADD, STDIN_FILENO, &ev);

    ev.data.fd = dev_fd;
    ev.events = EPOLLIN;
    // 将文件描述符添加到epoll实例中
    epoll_ctl(epoll_fd, EPOLL_CTL_ADD, dev_fd, &ev);

    char buf[64];
    int len;
    while(1)
    {
        // 等待事件发生
        int nfds = epoll_wait(epoll_fd, events, 8, 10000);
        if (nfds == -1)
        {
            perror("epoll_wait");
            exit(1);
        }
        else if (nfds == 0)
        {
            printf("timeout\n");
            continue;
        }
        for(int i = 0; i < nfds; i++)
        {
            if(events[i].data.fd == STDIN_FILENO)
            {
                memset(buf,0,sizeof(buf));
                len = read(STDIN_FILENO, buf, sizeof(buf));
                printf("input: %s\n", buf);
                write(dev_fd,buf,len-1);
                
            }
            else if(events[i].data.fd == dev_fd)
            {
                memset(buf,0,sizeof(buf));
                len = read(dev_fd,buf,sizeof(buf));
                if(len < 0){
                    perror("read failed");
                    continue;
                }
                printf("recv dev_fd: %s,len=%d\n", buf,len);
            }
        }
        sleep(1);
    }
}

int main()
{
    int dev_fd = open(DEVICE_FILE,O_RDWR);
    if(dev_fd < 0){
        perror("open device failed");
        exit(1);
    }

    // 测试epoll
    test_epoll(dev_fd);

    close(dev_fd);

    return 0;
}